slice與array的差異。
類型的差異
array屬於值類型,同屬於值類型的包含,基礎數據類型、結構體類型。
slice屬於引用類型,而同屬於引用類型的包含,字典、通道、函數類型。
宣告方式
從下面的範例看,宣告方式的差異。
package main
import "fmt"
func main() {
//array 宣告, string 類型
a := [5]string{"A","B","C","D","E"}
fmt.Printf("The value of a: %s\n\n", a)
//slice 宣告, 不指名容量, 容量就跟長度相同
s1 := make([]int, 5)
fmt.Printf("The length of s1: %d\n", len(s1))
fmt.Printf("The capacity of s1: %d\n", cap(s1))
fmt.Printf("The value of s1: %d\n\n", s1)
//slice 宣告, 用len、cap可以取得slice的length、capacity
s2 := make([]int, 5, 5)
fmt.Printf("The length of s2: %d\n", len(s2))
fmt.Printf("The capacity of s2: %d\n", cap(s2))
fmt.Printf("The value of s2: %d\n\n", s2)
}
https://play.golang.org/p/KWEYeVjvQML
array在宣告時,就確定長度。
a := [5]string{"A","B","C","D","E"}
slice 包含三個部分,pointer、length、capacity。
借用網路上的圖片,來說明slice的結構。
可以把slice看做對array的ㄧ層簡單的封裝。
s2 := make([]int, 5, 5)
解讀上面的宣告,宣告一個 slice,pointer 指向一個int array,而這個int array的長度和容量都是5。
s2 := make([]int, 5, 8)
更改成這個宣告的話,宣告一個 slice,pointer 指向一個int array,而這個int array的長度是5,容量是8。
package main
import "fmt"
func main() {
s1 := make([]int, 0)
fmt.Printf("The capacity of s1: %d\n", cap(s1))
for i := 1; i <= 5; i++ {
s1 = append(s1, i)
fmt.Printf("s1(%d): len: %d, cap: %d\n", i, len(s1), cap(s1))
}
fmt.Println()
}
https://play.golang.org/p/KlzlLlMkbj2
使用append的函數,把元素丟到slice s1中。
當容量為零時,append會新增一個容量。
當容量不夠時,append會以2的倍數增加slice的容量。
小總結:
array在宣告的時候,就確定長度,且長度固定。
slice的長度,可以隨著元素的數量增加而增長。
引用: